var crypto = require('crypto')
var express = require('express');
var axios = require('axios')
var querystring = require('querystring')
var randomstring = require('randomstring')
var router = express.Router()
var getRawBody = require('raw-body')
var contentType = require('content-type')
var convert = require('xml-js')

router.get('/', function(req, res, next) {
  const token = 'weixin'
  let { echostr, timestamp, nonce, signature } = req.query

  // 将token、timestamp、nonce三个参数进行字典序排序
  let str = [token, timestamp, nonce].sort().join('')
  let signStr = crypto.createHash('sha1').update(str).digest('hex')

  if (signStr === signature) {
    res.send(echostr)
  } else {
    res.send('error')
  }
})

router.get('/sign', async (req, res, next) => {
  // 1. 获取access_tocken
  // https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
  const appId = 'wx7ba8ee8a8beace33'
  const appSecret = 'd62705bd6fdf27441397683019077e20'
  const acResult = await axios.get(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appId}&secret=${appSecret}`)
  const { access_token } = acResult.data
  
  // 2.用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket（有效期7200秒，开发者必须在自己的服务全局缓存jsapi_ticket）：https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
  const jaResult = await axios.get(`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${access_token}&type=jsapi`)
  const { ticket } = jaResult.data

  // 3.生成signature
  // noncestr（随机字符串）, 
  // 有效的jsapi_ticket, 
  // timestamp（时间戳）,
  // url（当前网页的URL，不包含#及其后面部分）
  const noncestr = randomstring.generate(32)
  const timestamp = Math.floor(new Date().getTime() / 1000)
  const url = 'https://walter666.cn/'
  const signObj = {
    noncestr,
    timestamp,
    url,
    jsapi_ticket: ticket
  }

  const sortedSignObj = Object.keys(signObj).sort().reduce((obj, key) => {
    // 对象所有的Key是小写
    const key2 = key.toLowerCase()
    obj[key2] = signObj[key]
    return obj
  }, {})
  
  const string1 = querystring.stringify(sortedSignObj, null, null, { 
    encodeURIComponent: str => str
  })

  console.log(string1)
  
  const signature = crypto.createHash('sha1').update(string1).digest('hex')
  
  res.json({
    appId,
    timestamp,
    nonceStr: noncestr,
    signature
  })
})

function reply(xml) {
  const result = convert.xml2js(xml, {
    compact: true,
    textKey: 'value',
    cdataKey: 'value'
  })['xml']

  const obj = Object.keys(result).reduce((obj, key) => {
    obj[key] = result[key]['value']
    return obj
  }, {})

  return obj
}

router.post('/', function(req, res, next){
  getRawBody(req, {
    length: req.headers['content-length'],
    limit: '1mb',
    encoding: contentType.parse(req).parameters.charset
  }, function (err, string) {
    if (err) return next(err)
    try {
      const xml = string.toString()
      const obj = reply(xml)
      obj.Content = '<a href="https://walter666.cn/">test</a>'
      res.render('reply', obj)
    } catch(e) {
      // console.log(e)
    }
    next()
  })
})

module.exports = router